#include <iostream>

#include "Ai.hpp"
#include "world.hpp"

int Bresenham(int x1, int y1, int x2, int y2)
{
    int dx = x1-x2;
    if( dx < 0 ) dx = -dx;
    int dy = y1-y2;
    if( dy < 0 ) dy = -dy;
    int sx, sy;

    (x1 < x2) ? sx = 1 : sx = -1 ;
    (y1 < y2) ? sy = 1 : sy = -1 ;

    int err = dx - dy, e2;

    while(!(x1 == x2 && y1 == y2))
    {
        e2 = 2*err;

        if(e2 > -1*dy)
        {
            err = err - dy;
            x1 = x1 + sx;
        }
        if(e2 < dx)
        {
            err = err+dx;
            y1 = y1 + sy;
        }

        if(ai.world.exists(x1,y1))
        {
            if(ai.world.at(x1,y1).fruit != NULL || ai.world.isWalkable(&ai.world.at(x1,y1)))
                return -1;  //Tir "impossible" - on envoie le tireur bouler.
        }
    }

    return err;
}

int getSugarDropId(int x, int y)
{
     for( map<int,Object>::iterator it = ai.world.items.begin(); it != ai.world.items.end(); it++ ){
                if(it->second.type==SUGAR_DROP && it->second.position==&ai.world.at(x,y)) return it->second.id;
        }
}

map_chunk* getFreeSpaceAround(map_chunk* pos)
{
    int x = pos->X_coord, y = pos->Y_coord;
    int px, py;
    map_chunk *ret;

    px = x-1; py = y-1;
    if (ai.world.exists(px,py) && ai.world.isWalkable(&ai.world.at(px,py)))
        return &ai.world.at(px,py);

    px = x; py = y-1;
    if (ai.world.exists(px,py) && ai.world.isWalkable(&ai.world.at(px,py)))
        return &ai.world.at(px,py);

    px = x+1; py = y-1;
    if (ai.world.exists(px,py) && ai.world.isWalkable(&ai.world.at(px,py)))
        return &ai.world.at(px,py);

    px = x-1; py = y;
    if (ai.world.exists(px,py) && ai.world.isWalkable(&ai.world.at(px,py)))
        return &ai.world.at(px,py);

    px = x+1; py = y;
    if (ai.world.exists(px,py) && ai.world.isWalkable(&ai.world.at(px,py)))
        return &ai.world.at(px,py);

    px = x-1; py = y+1;
    if (ai.world.exists(px,py) && ai.world.isWalkable(&ai.world.at(px,py)))
        return &ai.world.at(px,py);

    px = x; py = y+1;
    if (ai.world.exists(px,py) && ai.world.isWalkable(&ai.world.at(px,py)))
        return &ai.world.at(px,py);

    px = x+1; py = y+1;
    if (ai.world.exists(px,py) && ai.world.isWalkable(&ai.world.at(px,py)))
        return &ai.world.at(px,py);

    return NULL;
}

void copyVectorElements(vector<Object*>* dest, vector<Object*>* src) {
    for (int i = 0; i < src->size(); i++) {
        dest->push_back((*src)[i]);
    }
}

vector<Object*> getObjectsInNeighborhood(map_chunk* pos)
{
    vector<Object*> objectsInNeighborhood;
    int x = pos->X_coord, y = pos->Y_coord;
    int px, py;
    map_chunk *ret;

    px = x-1; py = y-1;
    if (ai.world.exists(px,py))
        copyVectorElements(&objectsInNeighborhood, &ai.world.at(px,py).objects);

    px = x; py = y-1;
    if (ai.world.exists(px,py))
        copyVectorElements(&objectsInNeighborhood, &ai.world.at(px,py).objects);

    px = x+1; py = y-1;
    if (ai.world.exists(px,py))
        copyVectorElements(&objectsInNeighborhood, &ai.world.at(px,py).objects);

    px = x-1; py = y;
    if (ai.world.exists(px,py))
        copyVectorElements(&objectsInNeighborhood, &ai.world.at(px,py).objects);

    px = x+1; py = y;
    if (ai.world.exists(px,py))
        copyVectorElements(&objectsInNeighborhood, &ai.world.at(px,py).objects);

    px = x-1; py = y+1;
    if (ai.world.exists(px,py))
        copyVectorElements(&objectsInNeighborhood, &ai.world.at(px,py).objects);

    px = x; py = y+1;
    if (ai.world.exists(px,py))
        copyVectorElements(&objectsInNeighborhood, &ai.world.at(px,py).objects);

    px = x+1; py = y+1;
    if (ai.world.exists(px,py))
        copyVectorElements(&objectsInNeighborhood, &ai.world.at(px,py).objects);

    return objectsInNeighborhood;
}

//Renvoie le carré de la distance à vol d'oiseau
int distance(map_chunk* A, map_chunk* B){
    int dx = A->X_coord - B->X_coord;
    int dy = A->Y_coord - B->Y_coord;
    return dx*dx + dy*dy;
}


